package com.company.project.core.common;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description：操作执行linux命令
 * @Author:jiatianqi
 * @Date:2019/8/14
 */
@Slf4j
public class CMDUtils {

    /**
     * pdf转换为高质量html文件
     *
     * @param srcPath
     */
    public static void pdfToHtmlByDockerInside(String srcPath, String targetPath) {
        String convertCmd = "/usr/local/bin/pdf2htmlEX --zoom 1.3 --clean-tmp=0 --tmp-dir=/pdf " + srcPath + " ";
        execute(new ArrayList<String>() {{
            add(convertCmd);
        }});
    }

    /**
     * pdf转换为高质量html文件
     *
     * @param localPath
     * @param srcName
     * @param targetName
     */
    public static void pdfToHtmlByDockerOutside(String localPath, String srcName, String targetName) {
        String convertCmd = "docker run -ti --rm -v " + localPath +
                ":/pdf pdf2html:latest /usr/local/bin/pdf2htmlEX --zoom 1.3 --clean-tmp=0 --tmp-dir=/pdf " +
                srcName + " " + targetName;
        execute(new ArrayList<String>() {{
            add(convertCmd);
        }});
    }

    /**
     * woff字体文件转为图片
     *
     * @param srcPath
     */
    public static List<String> woff2Image(String srcPath, String targetPath) {
        String convertCmd = "python woff.py " + srcPath + " " + targetPath;
        List<String> result = executeWithResult(new ArrayList<String>() {{
            add(convertCmd);
        }});
        return result;
    }

    /**
     * woff字体文件转为图片 单个字体处理
     *
     * @param srcPath
     */
    public static List<String> woff2Image2(String srcPath, String targetPath) {
        String convertCmd = "python woff2.py " + srcPath + " " + targetPath;
        List<String> result = executeWithResult(new ArrayList<String>() {{
            add(convertCmd);
        }});
        return result;
    }

    /**
     * pdf转换为高质量docx文件
     *
     * @param srcPath
     */
    public static String pdfToDocx(String srcPath) {
        String convertCmd = "pdf2docx convert " + srcPath + " --multi_processing=True";
        execute(new ArrayList<String>() {{
            add(convertCmd);
        }});
        return srcPath.substring(0, srcPath.lastIndexOf('.')) + ".docx";
    }

    /**
     * pdf转换为高质量png图片
     *
     * @param srcImagePath
     * @param dstImagePath
     */
    public static void pdfToPng(String srcImagePath, String dstImagePath) {
        String convertCmd = "convert -density 150 -quality 100 " + srcImagePath + " " + dstImagePath;
        execute(new ArrayList<String>() {{
            add(convertCmd);
        }});
    }

    /**
     * 图片缩放
     *
     * @param srcImagePath
     * @param dstImagePath
     */
    public static void zoomImagemagic(String srcImagePath, String dstImagePath) {
        String convertCmd = "convert -resize '1024x>' " + srcImagePath + " " + dstImagePath;
        execute(new ArrayList<String>() {{
            add(convertCmd);
        }});
    }

    /**
     * 转换生成替换目标图片
     *
     * @param dirpath
     * @param filePath
     * @param srcImagePath
     * @param dstImagePath
     */
    public static void convertImagemagic(String dirpath, String filePath, String srcImagePath, String dstImagePath) {
        String convertCmd = dirpath + "addWaterMark.sh " + filePath + " " + srcImagePath + " " + dstImagePath;
        execute(new ArrayList<String>() {{
            add(convertCmd);
        }});
    }

    /**
     * 调用linux命令
     *
     * @param commands
     * @return
     */
    public static synchronized void execute(List<String> commands) {
        log.info("执行命令：{}", commands.toString());
        Runtime run = Runtime.getRuntime();
        Process proc = null;
        PrintWriter out = null;
        try {
            proc = run.exec("/bin/bash", null, null);
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
            for (String line : commands) {
                out.println(line);
            }
            out.println("exit");// 这个命令必须执行，否则in流不结束。
            //不用线程，单个执行
            new DealProcessSream(proc.getInputStream()).run();
            new DealProcessSream(proc.getErrorStream()).run();
            proc.waitFor(180, TimeUnit.SECONDS);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
            if (proc != null) {
                proc.destroy();
            }
        }
    }

    /**
     * 调用linux命令 返回结果
     *
     * @param commands
     * @return
     */
    public static synchronized List<String> executeWithResult(List<String> commands) {
        log.info("执行命令：{}", commands.toString());
        List<String> rspList = new ArrayList<>();
        Runtime run = Runtime.getRuntime();
        try {
            Process proc = run.exec("/bin/bash", null, null);
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
            for (String line : commands) {
                out.println(line);
            }
            out.println("exit");// 这个命令必须执行，否则in流不结束。
            String rspLine;
            while ((rspLine = in.readLine()) != null) {
                rspList.add(rspLine);
            }
            proc.waitFor(180, TimeUnit.SECONDS);
            in.close();
            out.close();
            proc.destroy();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return rspList;
    }

    /**
     * 从服务器上删除源文件
     *
     * @param path
     */
    public static void deleteFileOnServer(String path) {
        List<String> commands = new ArrayList<>();
        if (new File(path).exists()) {
            if (path.contains("\\")) {
                path = path.replace("\\", "/");
            }
            commands.add("rm -rf " + path);
        }
        execute(commands);
    }


    static class DealProcessSream extends Thread {
        private InputStream inputStream;

        public DealProcessSream(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        public void run() {
            InputStreamReader inputStreamReader = null;
            BufferedReader br = null;
            try {
                inputStreamReader = new InputStreamReader(
                        inputStream);
                br = new BufferedReader(inputStreamReader);
                // 打印信息
                String line = null;
                while ((line = br.readLine()) != null) {
                    log.info("readLine result:{}", line);
                }
                // 不打印信息
                //while (br.readLine() != null) ;
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } finally {
                try {
                    br.close();
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

}
